package org.scala.javafx.geometry

import javafx.scene.Node
import javafx.stage.Window
import javafx.scene.shape.Rectangle
import javafx.scene.Scene

case class Bounds2D(minX: Double, minY: Double, maxX: Double, maxY: Double) {
  def width = maxX - minX
  def height = maxY - minY
  
  def inflate(border: Double): Bounds2D = Bounds2D(
      minX - border, minY - border, maxX + border, maxY + border)

  def translate(point: Point2D): Bounds2D = Bounds2D(
      minX + point.x, minY + point.y, maxX + point.x, maxY + point.y)
}

object Bounds2D {
  def of(window: Window): Bounds2D = Bounds2D(
      window.getX(), window.getY(),
      window.getX() + window.getWidth(), window.getY() + window.getHeight())
      
  def of(rectangle: Rectangle): Bounds2D = Bounds2D(
      rectangle.getX(), rectangle.getY(),
      rectangle.getX() + rectangle.getWidth(),
      rectangle.getY() + rectangle.getHeight())

  def layoutOf(rectangle: Rectangle): Bounds2D = Bounds2D(
      rectangle.getLayoutX(), rectangle.getLayoutY(),
      rectangle.getLayoutX() + rectangle.getWidth(),
      rectangle.getLayoutY() + rectangle.getHeight())
      
  def layoutOf(node: Node): Bounds2D = {
    val layoutBounds = node.getLayoutBounds()
    val sceneBounds = node.localToScene(layoutBounds)
    
    Bounds2D(sceneBounds.getMinX(), sceneBounds.getMinY(), sceneBounds.getMaxX(), sceneBounds.getMaxY())
  }
  
  def fromScreenOf(node: Node): Bounds2D = {
    val scene = node.getScene()
    val window = scene.getWindow()
    Bounds2D.layoutOf(node).translate(Point2D.minOf(scene)).translate(Point2D.minOf(window))
  }
  
  def fromWindowOf(node: Node): Bounds2D = {
    val scene = node.getScene()
    Bounds2D.layoutOf(node).translate(Point2D.minOf(scene))
  }
  
  def fromScreenOf(scene: Scene): Bounds2D = {
    val window = scene.getWindow()
    val minX = scene.getX() + window.getX()
    val minY = scene.getY() + window.getY()
    Bounds2D(minX, minY, minX + scene.getWidth(), minY + scene.getHeight())
  }
}
